import 'dart:developer';

import 'package:dio/dio.dart';
import 'package:shop/common/AppStorge.dart';
import 'package:shop/common/BaseError.dart';
import 'package:shop/common/UrlConfig.dart';

import 'package:shop/utils/Storage.dart';

//网络请求工具类
class MyHttp {
  static MyHttp _instance = MyHttp._internal();
  Dio _dio;

  //单例模式
  factory MyHttp() => _instance;

  //第一次使用时初始化
  MyHttp._internal() {
    if (null == _dio) {
      BaseOptions options = new BaseOptions(
        connectTimeout: 15000,
        receiveTimeout: 3000,
      );
      _dio = new Dio(options);

      _dio.interceptors
          .add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
        if (options.data is FormData) {
          (options.data as FormData).fields
            ..add(MapEntry("token", MyStorge.token))
            ..add(MapEntry(
                "time", DateTime.now().millisecondsSinceEpoch.toString()));
        }
        return options;
      }, onResponse: (Response response) async {
        if (response.data["Status"] != 200) {
          log('++++++++++++返回结果状态异常+++++++++++++');
          log("状态码:" + response.data["Status"].toString());
          log("url:" + response.request.path.toString());
          log("请求体:" + response.request.data.fields.toString());
          log("msg: " + response.data['Msg'].toString());
          log('++++++++++++返回结果打印结束+++++++++++++');
        }
        print("${response.request.path.toString()}  请求体:" +
            response.request.data.fields.toString());
        return response;
      }, onError: (DioError e) async {
        log("++++++++++++请求出错信息+++++++++++++++");
        log("出错: " + e.error.toString());
        log("请求地址: " + e.request.path.toString());
        log("请求方法: " + e.request.method.toString());
        log("请求参数: " + e.request.data.fields.toString());
        log("状态码: " + e.response?.statusCode.toString());
        log("++++++++++++信息打印结束+++++++++++++++");
      }));
    }
  }

  ///如果doCatch为true (默认为true) ,直接返回 data 中body 数据
  /// 如果doCatch为false , 则不作处理 返回 { "mas":"", code:1,data:{}}

  /// [url]: 接口地址 ;
  /// [data]: map类型的请求数据;
  /// [needToken]: 是否携带token , 默认会自动携带token;
  /// [doCatch]: 是否自动处理异常 , 比如返回102的时候自动跳转到登录页面;
  /// [cache]: 是否将本次结果缓存 , 如果网络异常 , 则直接返回上一次正常请求的结果
  Future<Map<String, dynamic>> post(
    String url, {
    Map<String, dynamic> data,
    bool needToken = true,
    bool doCatch = true,
    bool cache = false,
  }) async {
    return _getData(url, data, "post", needToken, doCatch, cache);
  }

  Future<Map<String, dynamic>> _getData(String url, Map<String, dynamic> data,
      String resultType, bool needToken, bool doCatch, bool cache) async {
    String storgeKey = url;
    if (needToken) {
      if (MyStorge.token == "") throw BaseException("102", "未登录");
    }
    if (!url.startsWith("http")) url = UrlConfig.baseUrl + url; //补全url
    FormData formData = new FormData.fromMap(data ?? {});
    Response response;
    Map result;
    try {
      response = await _dio.post("$url", data: formData);

      if (cache) {
        StorageUtil.setMap(storgeKey, response.data);
      }
      result = response.data;
    } catch (e) {
      if (cache) {
        log("从缓存中获取: ");
        result = StorageUtil.getMap(storgeKey);
        print(result.toString());
      }
    }

    if (result["Status"] != 200 && doCatch)
      throw BaseException(
          result["Status"].toString(), result['Msg'].toString());

    if (doCatch) {
      return result["Data"];
    }
    return result;
  }
}
